package org.jeecg.modules.xindian.reconciliation.controller;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.xindian.reconciliation.controller.req.EditPolicyReq;
import org.jeecg.modules.xindian.reconciliation.controller.req.IdWapper;
import org.jeecg.modules.xindian.reconciliation.controller.req.PolicyRelationExcel;
import org.jeecg.modules.xindian.reconciliation.controller.req.ReportReq;
import org.jeecg.modules.xindian.reconciliation.controller.rsp.BrokerageFeeSettlementInfoExcel;
import org.jeecg.modules.xindian.reconciliation.controller.rsp.SettlementPolicyInfoExcel;
import org.jeecg.modules.xindian.reconciliation.dto.rsp.SalesmanManagerExcel;
import org.jeecg.modules.xindian.reconciliation.entity.*;
import org.jeecg.modules.xindian.reconciliation.enums.DeleteFlagEnum;
import org.jeecg.modules.xindian.reconciliation.enums.RelationType;
import org.jeecg.modules.xindian.reconciliation.mapper.PolicySettlementStatisticsMapper;
import org.jeecg.modules.xindian.reconciliation.service.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.apache.shiro.authz.annotation.RequiresPermissions;

 /**
 * @Description: 业务员信息表
 * @Author: jeecg-boot
 * @Date:   2024-04-11
 * @Version: V1.0
 */
@Api(tags="业务员结算模块")
@RestController
@RequestMapping("/reconciliation/salesman")
@Slf4j
public class SalesmanController extends JeecgController<Salesman, ISalesmanService> {
	@Autowired
	private ISalesmanService salesmanService;
	 @Autowired
	 private ISalesmanManagerRateService managerRateService;
	 @Autowired
	 private ISalesmanSettlementInfoService salesmanSettlementInfoService;

	 @Autowired
	 private PolicySettlementStatisticsMapper settlementInfoMapper;
	 @Value(value = "${jeecg.path.upload}")
	 private String uploadpath;
	/**
	 *
	 * 分页列表查询
	 *
	 * @param salesman
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	//@AutoLog(value = "业务员信息表-分页列表查询")
	@ApiOperation(value="业务员-分页查询", notes="业务员-分页查询")
	@GetMapping(value = "/list")
	public Result<IPage<Salesman>> queryPageList(Salesman salesman,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<Salesman> queryWrapper = QueryGenerator.initQueryWrapper(salesman, req.getParameterMap());
		Page<Salesman> page = new Page<Salesman>(pageNo, pageSize);
		IPage<Salesman> pageList = salesmanService.pageQuery(page);
		return Result.OK(pageList);
	}



	 /**
	 *   添加
	 *
	 * @param salesman
	 * @return
	 */
	@AutoLog(value = "新增业务员")
	@ApiOperation(value="新增业务员", notes="新增业务员")
	//@RequiresPermissions("reconciliation:salesman:add")
	@PostMapping(value = "/add")
	public Result<String> add(@RequestBody Salesman salesman) {
		Assert.notNull(salesman.getName(),"业务员名称不能为空");
		salesman.setDeleteFlag(DeleteFlagEnum.N);
		salesmanService.save(salesman);
		return Result.OK("添加成功！");
	}


	 /**
	  * 分页列表查询
	  *
	  * @param salesman
	  * @param pageNo
	  * @param pageSize
	  * @param req
	  * @return
	  */
	 //@AutoLog(value = "业务员信息表-分页列表查询")
	 @ApiOperation(value="业务员客户管理-分页查询", notes="业务员客户管理-分页查询")
	 @GetMapping(value = "/managerList")
	 public Result<IPage<SalesmanManagerRate>> managerList(Salesman salesman,
												  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
												  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
												@RequestParam(name="salesmanId") String salesmanId,
												@RequestParam(name="company", required =false) String company,
												  HttpServletRequest req) {
		 Assert.notNull(salesmanId,"业务员id不能为空");
		 Page<SalesmanManagerRate> page = new Page<>(pageNo, pageSize);
		 LambdaQueryChainWrapper<SalesmanManagerRate> queryChainWrapper =    managerRateService.lambdaQuery();
		 queryChainWrapper.eq(SalesmanManagerRate::getSalesmanId,salesmanId);
		 queryChainWrapper.eq(SalesmanManagerRate::getDeleteFlag,DeleteFlagEnum.N);
		 if(StringUtils.hasText(company)){
			 queryChainWrapper.like(SalesmanManagerRate::getCompany,company);
		 }
		 IPage<SalesmanManagerRate> pageList = queryChainWrapper.page(page);
		 pageList.getRecords().forEach(SalesmanManagerRate::buildConfigs);
		 return Result.OK(pageList);
	 }


	 /**
	  * 业务员绑定客户信息
	  * @param salesmanManagerRate
	  * @return
	  */
	 @AutoLog(value = "业务员绑定客户信息")
	 @ApiOperation(value="业务员绑定客户信息", notes="业务员绑定客户信息")
	 //@RequiresPermissions("reconciliation:salesman:add")
	 @PostMapping(value = "/managerRateAdd")
	 public Result<String> managerRateAdd(@RequestBody SalesmanManagerRate salesmanManagerRate) {
		 Salesman salesman =  salesmanService.getById(salesmanManagerRate.getSalesmanId());
		 Assert.notNull(salesman,"业务员不能为空");
		 managerRateService.save(salesmanManagerRate);
		 salesmanService.updateById(salesman);
		 return Result.OK("添加成功！");
	 }


	 /**
	  * 编辑
	  * @param salesmanManagerRate
	  * @return
	  */
	 @AutoLog(value = "业务员修改客户比例")
	 @ApiOperation(value = "业务员修改客户比例", notes = "业务员修改客户比例")
	 //@RequiresPermissions("reconciliation:channel_settlement_config:edit")
	 @PostMapping(value = "/managerRateEdit")
	 public Result<String> edit(@RequestBody SalesmanManagerRate salesmanManagerRate) {
		 managerRateService.updateById(salesmanManagerRate);
		 return Result.OK("编辑成功!");
	 }


	 /**
	  * 业务员删除客户
	  * @param idWapper
	  * @return
	  */
	 @AutoLog(value = "删除业务员")
	 @ApiOperation(value = "删除业务员", notes = "删除业务员")
	 //@RequiresPermissions("reconciliation:channel_settlement_config:edit")
	 @PostMapping(value = "/managerDelete")
	 public Result<String> managerDelete(@RequestBody IdWapper idWapper) {
		 salesmanService.deleteSalesman(idWapper.getId());
		 return Result.OK("删除成功成功!");
	 }


	 /**
	  * 业务员删除客户
	  * @param idWapper
	  * @return
	  */
	 @AutoLog(value = "业务员删除客户")
	 @ApiOperation(value = "业务员删除客户", notes = "业务员删除客户")
	 //@RequiresPermissions("reconciliation:channel_settlement_config:edit")
	 @PostMapping(value = "/managerRateDelete")
	 public Result<String> delete(@RequestBody IdWapper idWapper) {
		 Assert.notNull(idWapper.getId(),"id不能为空");
		 managerRateService.deleteSalesmanManagerRate(idWapper.getId());
		 return Result.OK("删除成功成功!");
	 }


	 /**
	  * 保单明细
	  *
	  * @param idWapper
	  */
	 //@RequiresPermissions("banck:insurance_hangzhou_back:exportXls")@\
	 @ApiOperation(value = "业务员客户导出", notes = "业务员客户导出")
	 @GetMapping(value = "/exportSalesmanManager")
	 public ModelAndView exportSalesmanManager(IdWapper idWapper, HttpServletRequest request) {
		 Assert.notNull(idWapper.getSalesmanId(), "数据主键不能为空");
		 Salesman salesman =  salesmanService.getById(idWapper.getSalesmanId());
		 List<SalesmanManagerRate> policyInfoExcels = managerRateService.queryBySalesmanId(idWapper.getSalesmanId());
		List<SalesmanManagerExcel>  excels = policyInfoExcels.stream().map(one->{
			 SalesmanManagerExcel excel = new SalesmanManagerExcel();
			 excel.setCompany(one.getCompany());
			 return excel;
		 }).collect(Collectors.toList());
		 return this.exportXls(request, excels, SalesmanManagerExcel.class, salesman.getName()+"客户明细");
	 }



	 /**
	  * 账单周期记录
	  *
	  * @return
	  */
	 //@AutoLog(value = "杭州银行资金流水-分页列表查询")
	 @ApiOperation(value = "账单周期记录", notes = "账单周期记录")
	 @PostMapping(value = "/info")
	 public Result<IPage<SalesmanSettlementInfo>> info(@RequestBody ReportReq req) {
		 log.info("账单周期请求参数如下:{}", req);
		 Assert.notNull(req.getPageSize(), "页数不能为空");
		 Assert.notNull(req.getPageIndex(), "页码不能为空");
		 Page<SalesmanSettlementInfo> page = new Page<>(req.getPageIndex(), req.getPageSize());
		 return Result.ok(salesmanSettlementInfoService.querySalesmanSettlementInfo(page,req.getDate()));
	 }


	 /**
	  * 同步上个月数据
	  *
	  * @return
	  */
	 @ApiOperation(value = "同步上个月数据", notes = "同步上个月数据")
	 @PostMapping(value = "/synchronizeLastMonth")
	 public Result<?> synchronizeLastMonth() {
		 salesmanSettlementInfoService.synchronizeLastMonth();
		 return Result.ok();
	 }
	 private Result<?> uploadPolicyFile(@RequestBody  EditPolicyReq editPolicyReq) {
		 Assert.notNull(editPolicyReq.getId(), "结算记录Id不能为空");
		 Assert.notNull(editPolicyReq.getUrl(), "文件地址不能为空");
		 String id = editPolicyReq.getId();
		 // 获取上传文件对象
		 FileInputStream fileInputStream = null;
		 try {
			 fileInputStream = new FileInputStream(uploadpath + File.separator+editPolicyReq.getUrl());
			 ImportParams params = new ImportParams();
			 params.setTitleRows(0);
			 params.setHeadRows(0);
			 params.setNeedSave(true);
			 List<PolicyRelationExcel> list = ExcelImportUtil.importExcel(fileInputStream, PolicyRelationExcel.class, params);
			 AtomicReference<Integer> rowId = new AtomicReference<>(1);
			 list.forEach(pt -> {
				 rowId.getAndSet(rowId.get() + 1);
				 Assert.notBlank(pt.getPolicyNo(), "第{}行保单号为空", rowId.get());
				 Assert.notNull(pt.getRate(), "第{}行费率为空", rowId.get());
				 Assert.checkBetween(pt.getRate(), BigDecimal.ZERO,BigDecimal.ONE);
			 });
			 //计算统计信息
			 salesmanSettlementInfoService.loadSettlementByUpLoadFile(id, list);
			 return Result.OK("文件导入成功！数据行数:" + list.size());
		 } catch (Exception e) {
			 log.error(e.getMessage(), e);
			 return Result.error("文件导入失败:" + e.getMessage());
		 } finally {
			 try {
				 fileInputStream.close();
			 } catch (IOException e) {
				 log.error("关闭资源失败", e);
			 }
		 }
	 }


	 /**
	  * 修改保单
	  *
	  * @return
	  */
	 //@AutoLog(value = "杭州银行资金流水-分页列表查询")
	 @ApiOperation(value = "修改保单", notes = "修改保单")
	 @PostMapping(value = "/uploadEditPolicy")
	 public Result<?> uploadEditPolicy(@RequestBody  EditPolicyReq editPolicyReq)
	 {
		 Result<?> list = uploadPolicyFile(editPolicyReq);
		 if (list != null) return list;
		 return Result.ok();
	 }


	 /**
	  * 确认保单
	  *
	  * @return
	  */
	 //@AutoLog(value = "杭州银行资金流水-分页列表查询")
	 @ApiOperation(value = "确认保单", notes = "确认保单")
	 @PostMapping(value = "/confirmPolicy")
	 public Result<?> confirmPolicy(@RequestBody IdWapper idWapper) {
		 Assert.notNull(idWapper.getId(), "数据主键不能为空");
		 salesmanSettlementInfoService.confirmPolicy(idWapper.getId());
		 return Result.ok();
	 }

	 /**
	  * 保单明细
	  *
	  * @param idWapper
	  */
	 //@RequiresPermissions("banck:insurance_hangzhou_back:exportXls")@\
	 @ApiOperation(value = "保单明细导出", notes = "保单明细导出")
	 @GetMapping(value = "/exportXlsPolicyInfo")
	 public ModelAndView exportXlsPolicyInfo(IdWapper idWapper, HttpServletRequest request) {
		 Assert.notNull(idWapper.getId(), "数据主键不能为空");
		 List<SettlementPolicyInfoExcel> policyInfoExcels = settlementInfoMapper.querySalemanPolicyInfo(idWapper.getId());
		 return this.exportXls(request, policyInfoExcels, SettlementPolicyInfoExcel.class, "保单明细");
	 }


	 @PostMapping(value = "edit")
	 public Result<?> edit(@RequestBody Salesman salesman) {
		 salesmanService.updateById(salesman);
		 return Result.OK("修改成功！");
	 }


	 /**
	  * 经纪费明细
	  *
	  * @param idWapper
	  */
	 //@RequiresPermissions("banck:insurance_hangzhou_back:exportXls")@\
	 @ApiOperation(value = "经纪费明细", notes = "经纪费明细")
	 @GetMapping(value = "/exportXlsBrokerageFeeInfo")
	 public ModelAndView exportXlsBrokerageFeeInfo(IdWapper idWapper, HttpServletRequest request) {
		 Assert.notNull(idWapper.getId(), "数据主键不能为空");
		 List<BrokerageFeeSettlementInfoExcel> policyInfoExcels = settlementInfoMapper.querySalesmanFeeBySettlementId(idWapper.getId());
		 return this.exportXls(request, policyInfoExcels, BrokerageFeeSettlementInfoExcel.class, "经纪费明细");
	 }

//    /**
//     * 经纪费结算单
//     *
//     * @param idWapper
//     */
//    //@RequiresPermissions("banck:insurance_hangzhou_back:exportXls")@\
//    @ApiOperation(value = "经纪费结算单", notes = "经纪费结算单")
//    @GetMapping(value = "/exportXlsBrokerageFeeSettlementInfo")
//    public ModelAndView exportXlsBrokerageFeeSettlementInfo(IdWapper idWapper,HttpServletRequest request) {
//        Assert.notNull(idWapper.getId(), "数据主键不能为空");
//        List<BrokerageFeeSettlementInfoExcel> policyInfoExcels = relationService.queryBrokerageFeeBySettlementId(idWapper.getId());
//        return this.exportXls(request, policyInfoExcels, BrokerageFeeSettlementInfoExcel.class, "经纪费明细");
//    }


	 /**
	  * 导出excel
	  *
	  * @param request
	  */
	 protected <T> ModelAndView exportXls(HttpServletRequest request, List<T> exportList, Class<T> clazz, String title) {
		 // Step.1 组装查询条件
		 LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		 // Step.3 AutoPoi 导出Excel
		 ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
		 //此处设置的filename无效 ,前端会重更新设置一下
		 mv.addObject(NormalExcelConstants.FILE_NAME, title);
		 mv.addObject(NormalExcelConstants.CLASS, clazz);
		 //update-begin--Author:liusq  Date:20210126 for：图片导出报错，ImageBasePath未设置--------------------
		 ExportParams exportParams = new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title);
		 exportParams.setType(ExcelType.HSSF);
		 mv.addObject(NormalExcelConstants.PARAMS, exportParams);
		 mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
		 return mv;
	 }
}
